package cn.haiway.drools.utils;

import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * @author Haiway  on  2019-04-19
 */
public class RedisUtil {
    private static final String API_COUNT_KEY_PREFIX = "api";

    /**
     * Kjar的key
     */
    private static final String KJAR_KEY = "%s:%s:%s";

    /**
     * 缓存时间60分钟
     */
    public static final long ONE_HOUR_EXPIRE = 60L;

    /**
     * 获取Kjar的key
     * @return
     */
    public static String kjarKey(String groupId,String artifactId,String version) {
        return String.format(KJAR_KEY, groupId,artifactId,version).trim();
    }



    /**
     * 操作Value类型数据
     * 根据key缓存中获取value
     * @param key
     * @param redisTemplate
     * @param <T>
     * @return
     */
    public static <T> T valueGet(Object key, RedisTemplate redisTemplate) {
        Object object = redisTemplate.opsForValue().get(key);
        if (null != object) {
            return (T) object;
        }
        return null;
    }

    /**
     * 根据key删除redis中的缓存
     * @param key redis中key
     * @param redisTemplate redis模版
     */
    public static void delete(Object key,RedisTemplate redisTemplate){
        redisTemplate.delete(key);
    }

    /**
     * 根据key获取缓存中的值，如果不存在则从supplier中获取并放入缓存中。
     * 默认失效时间24小时
     * @param key 缓存key
     * @param redisTemplate redis模版
     * @param supplier 函数
     * @param <T> 范型
     * @return 范型
     */
    public static <T> T valueGetWithSupplier(Object key, RedisTemplate redisTemplate, Supplier<T> supplier) {
        return valueGetWithSupplier(key, redisTemplate, supplier, 24, TimeUnit.HOURS);
    }

    /**
     * 根据key获取缓存中的值，如果不存在则从supplier中获取并放入缓存中。
     * @param key 缓存key
     * @param redisTemplate redis模版
     * @param supplier 函数
     * @param <T> 范型
     * @param timeUnit 失效时间
     * @return 范型
     */
    public static <T> T valueGetWithSupplier(Object key, RedisTemplate redisTemplate, Supplier<T> supplier, long timeOut, TimeUnit timeUnit) {
        Object object = redisTemplate.opsForValue().get(key);
        T target;
        if (null == object) {
            target = supplier.get();
            valueAdd(key, target, redisTemplate, timeOut, timeUnit);
        } else {
            target = (T) object;
        }
        return target;
    }

    public static void valueAdd(Object key, Object value, RedisTemplate redisTemplate, long timeOut, TimeUnit timeUnit) {
        valueAdd(key, value, timeOut, timeUnit, redisTemplate);
    }

    public static void valueAdd(Object key, Object value, long timeOut, TimeUnit timeUnit, RedisTemplate redisTemplate) {
        redisTemplate.opsForValue().set(key, value);
        redisTemplate.expire(key, timeOut, timeUnit);
    }

    public static void valueAdd(Object key,Object value,RedisTemplate redisTemplate){
        redisTemplate.opsForValue().set(key, value);
    }

}
